package alibaba

import (
	"testing"

	"github.com/stretchr/testify/require"
)

func Test_AGitFlowPatterns(t *testing.T) {
	for _, tc := range []struct {
		desc                  string
		agitPatterns          []string
		tagsPatterns          []string
		headsPatterns         []string
		mergeRequestsPatterns []string
		ref                   string
		expected              bool
		wantErr               bool
	}{
		{
			desc:         "normal agitflow patterns with agitflow ref",
			agitPatterns: []string{"refs/for", "refs/for-review", "refs/drafts"},
			ref:          "refs/for/master",
			expected:     true,
		},
		{
			desc:         "normal agitflow patterns with another agitflow ref",
			agitPatterns: []string{"refs/for", "refs/for-review/", "refs/drafts/**"},
			ref:          "refs/drafts/yet/another/branch",
			expected:     true,
		},
		{
			desc:         "normal agitflow patterns with agitflow ref",
			agitPatterns: []string{"refs/for", "refs/for-review/", "refs/drafts/**"},
			ref:          "refs/merge-requests/100/head",
			expected:     false,
		},
		{
			desc:         "normal agitflow patterns with agitflow ref",
			agitPatterns: []string{"refs/for", "refs/for-review/", " "},
			wantErr:      true,
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			detector, err := NewGlobsDetector(tc.agitPatterns, tc.tagsPatterns, tc.headsPatterns, tc.mergeRequestsPatterns)
			if tc.wantErr {
				require.Error(t, err)
				return
			}
			require.NoError(t, err)
			require.Equal(t, tc.expected, detector.IsAGitFlow(tc.ref))
		})
	}
}

func Test_TagsPatterns(t *testing.T) {
	for _, tc := range []struct {
		desc                  string
		agitPatterns          []string
		tagsPatterns          []string
		headsPatterns         []string
		mergeRequestsPatterns []string
		ref                   string
		expected              bool
		wantErr               bool
	}{
		{
			desc:         "normal tag ref",
			tagsPatterns: []string{"refs/tags"},
			ref:          "refs/tags/v1.0",
			expected:     true,
		},
		{
			desc:         "complicated tag ref",
			tagsPatterns: []string{"refs/tags"},
			ref:          "refs/tags/v1/v0",
			expected:     true,
		},
		{
			desc:         "normal head ref",
			tagsPatterns: []string{"refs/tags"},
			ref:          "refs/heads/master",
			expected:     false,
		},
		{
			desc:         "normal merge-requests ref",
			tagsPatterns: []string{"refs/tags"},
			ref:          "refs/merge-requests/100/head",
			expected:     false,
		},
		{
			desc:         "empty tag ref pattern",
			tagsPatterns: []string{""},
			wantErr:      true,
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			detector, err := NewGlobsDetector(tc.agitPatterns, tc.tagsPatterns, tc.headsPatterns, tc.mergeRequestsPatterns)
			if tc.wantErr {
				require.Error(t, err)
				return
			}
			require.NoError(t, err)
			require.Equal(t, tc.expected, detector.IsTags(tc.ref))
		})
	}
}

func Test_HeadsPatterns(t *testing.T) {
	for _, tc := range []struct {
		desc                  string
		agitPatterns          []string
		tagsPatterns          []string
		headsPatterns         []string
		mergeRequestsPatterns []string
		ref                   string
		expected              bool
		wantErr               bool
	}{
		{
			desc:          "normal head ref",
			headsPatterns: []string{"refs/heads"},
			ref:           "refs/heads/master",
			expected:      true,
		},
		{
			desc:          "complicated head ref",
			headsPatterns: []string{"refs/heads"},
			ref:           "refs/heads/yunhuai/develop",
			expected:      true,
		},
		{
			desc:          "normal tag ref",
			headsPatterns: []string{"refs/heads"},
			ref:           "refs/tags/v1.0",
			expected:      false,
		},
		{
			desc:          "normal merge-requests ref",
			headsPatterns: []string{"refs/heads"},
			ref:           "refs/merge-requests/100/head",
			expected:      false,
		},
		{
			desc:          "empty head ref pattern",
			headsPatterns: []string{""},
			wantErr:       true,
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			detector, err := NewGlobsDetector(tc.agitPatterns, tc.tagsPatterns, tc.headsPatterns, tc.mergeRequestsPatterns)
			if tc.wantErr {
				require.Error(t, err)
				return
			}
			require.NoError(t, err)
			require.Equal(t, tc.expected, detector.IsHeads(tc.ref))
		})
	}
}

func Test_MergeRequestPatterns(t *testing.T) {
	for _, tc := range []struct {
		desc                  string
		agitPatterns          []string
		tagsPatterns          []string
		headsPatterns         []string
		mergeRequestsPatterns []string
		ref                   string
		expected              bool
		wantErr               bool
	}{
		{
			desc:                  "normal merge-request ref",
			mergeRequestsPatterns: []string{"refs/merge-requests"},
			ref:                   "refs/merge-requests/100/head",
			expected:              true,
		},
		{
			desc:                  "normal tag ref",
			mergeRequestsPatterns: []string{"refs/merge-requests"},
			ref:                   "refs/tags/v1.0",
			expected:              false,
		},
		{
			desc:                  "normal heads ref",
			mergeRequestsPatterns: []string{"refs/merge-requests"},
			ref:                   "refs/heads/master",
			expected:              false,
		},
		{
			desc:                  "empty merge-requests ref pattern",
			mergeRequestsPatterns: []string{""},
			wantErr:               true,
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			detector, err := NewGlobsDetector(tc.agitPatterns, tc.tagsPatterns, tc.headsPatterns, tc.mergeRequestsPatterns)
			if tc.wantErr {
				require.Error(t, err)
				return
			}
			require.NoError(t, err)
			require.Equal(t, tc.expected, detector.IsMergeRequests(tc.ref))
		})
	}
}
